﻿namespace RainEngine.Rendering
{
    /// <summary>
    /// 保存每帧中节点信息的结构体
    /// </summary>
    public struct RenderStatistics
    {
        /// <summary>
        /// 正在更新的节点数量
        /// </summary>
        public ushort nodesUpdated;

        /// <summary>
        /// 可以被更新的节点数量
        /// </summary>
        public ushort nodesEnabled;

        /// <summary>
        /// 可见的节点数量
        /// </summary>
        public ushort nodesVisible;

        /// <summary>
        /// 实际被绘制的节点数量
        /// </summary>
        public ushort nodesRendered;

        /// <summary>
        /// 绘制的UI节点数量
        /// </summary>
        public ushort uiNodesRendered;

        /// <summary>
        /// 不可以被剔除的节点数量
        /// </summary>
        public ushort nodesCullingDisabled;

        /// <summary>
        /// 在逻辑视锥体之外，因此被剔除的节点数量
        /// </summary>
        public ushort nodesBoundingBoxCulled;

        /// <summary>
        /// 在视锥体之内但在允许距离之外，因此被剔除的节点数量
        /// </summary>
        public ushort nodesDistanceCulled;

        /// <summary>
        /// GPU处理的三角形图元数量
        /// </summary>
        public uint trisRendered;        

        /// <summary>
        /// 将计数器重置为0
        /// </summary>
        public void Reset()
        {
            nodesEnabled = 0;
            nodesUpdated = 0;
            nodesVisible = 0;
            nodesRendered = 0;
            uiNodesRendered = 0;
            nodesBoundingBoxCulled = 0;
            nodesDistanceCulled = 0;
            nodesCullingDisabled = 0;
            trisRendered = 0;
        }

        /// <summary>
        /// 将数据复制到给定的RenderStatistics类型的target目标
        /// </summary>
        /// <param name="target"></param>
        public void CopyTo(ref RenderStatistics target)
        {
            target.nodesEnabled = nodesEnabled;
            target.nodesUpdated = nodesUpdated;
            target.nodesVisible = nodesVisible;
            target.nodesRendered = nodesRendered ;
            target.uiNodesRendered = uiNodesRendered;
            target.nodesBoundingBoxCulled = nodesBoundingBoxCulled;
            target.nodesDistanceCulled = nodesDistanceCulled;
            target.nodesCullingDisabled = nodesCullingDisabled;
            target.trisRendered = trisRendered;            
        }
    }

    /// <summary>
    /// 保存每帧中帧数信息的结构体
    /// </summary>
    public struct RenderStatisticsAggregate
    {
        /// <summary>
        /// 计时器。它是一个未经初始化的引用，调用Reset()会创建一个计时器实例
        /// </summary>
        public System.Diagnostics.Stopwatch aggregateTimer;

        /// <summary>
        /// 一次更新过程所用的最长时间
        /// </summary>
        public long maxUpdateMilliseconds;

        /// <summary>
        /// 更新过程所用的总时间
        /// </summary>
        public long totalUpdateMilliseconds;

        /// <summary>
        /// 一次绘制过程所用的最长时间
        /// </summary>
        public long maxFrameRenderMilliseconds;

        /// <summary>
        /// 绘制过程所用的总时间
        /// </summary>
        public long totalRenderMilliseconds;

        /// <summary>
        /// 一段时间内（默认为250毫秒）绘制的帧数量
        /// </summary>
        public int frameCount;

        /// <summary>
        /// 一段时间内（默认为250毫秒）调用Update的次数
        /// </summary>
        public int updateCount;

        /// <summary>
        /// 返回每帧的平均用时，单位毫秒
        /// </summary>
        public float AvgMillisecondsPerFrame
        {
            get
            {
                return (float)totalRenderMilliseconds / frameCount;
            }
        }

        /// <summary>
        /// 将计数器重置为0
        /// </summary>
        public void Reset()
        {
            frameCount = 0;
            updateCount = 0;
            maxFrameRenderMilliseconds = 0;
            totalUpdateMilliseconds = 0;
            maxUpdateMilliseconds = 0;
            totalRenderMilliseconds = 0;
            if (aggregateTimer == null)
            {
                aggregateTimer = System.Diagnostics.Stopwatch.StartNew();
                aggregateTimer.Start();
            }
            else
            {
                aggregateTimer.Reset();
                aggregateTimer.Start();
            }
        }

        /// <summary>
        /// 将数据复制到RenderStatisticsAgregate类型的target参数。
        /// </summary>
        /// <param name="target"></param>
        public void CopyTo(ref RenderStatisticsAggregate target)
        {            
            target.aggregateTimer = aggregateTimer;
            target.frameCount = frameCount;
            target.updateCount = updateCount;
            target.maxUpdateMilliseconds = maxUpdateMilliseconds;
            target.totalUpdateMilliseconds = totalUpdateMilliseconds;
            target.maxFrameRenderMilliseconds = maxFrameRenderMilliseconds;
            target.totalRenderMilliseconds = totalRenderMilliseconds;
        }
    }
    
}
